/*
 * @Author: Snitro
 * @Date: 2021-05-19 11:44:57
 * @LastEditors: Snitro
 * @LastEditTime: 2021-05-23 14:26:41
 * @Description: file content
 */

#include "inputer.h"

extern ADC_HandleTypeDef hadc1;

uint16_t dma_buffer[100];

void ADC_Init() {
    HAL_ADC_Start_IT(&hadc1);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t *)dma_buffer, 100);
    HAL_ADC_Start(&hadc1);
}

void simple_tester() {
    if (getUidSet())
        setRealAvd((int)(Data_Reader(0) * 1000 / getUidSet()));
    else
        setRealAvd(0);
}

void tester() {
    simple_tester();

    setfH(0);
    clear_data();
    refresh_page1();

    frequency_output(1000);
    vdif_output(12);
    vcom_output(0);

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);

    double avd = 0, db, temp;

    uint32_t f = 1000, fH;

    db = Data_Reader(0) * 1000 / 12;

    setAvd((int)db);
    avd = db / 10;

    relay_driver(1);

    temp = Data_Reader(0) * 1000 / 12;

    setRid((int)(1000 * temp / (db - temp)));

    relay_driver(0);
    frequency_output(f);

    fH = 0;

    for (; f <= 1500000; f += 1000) {
        frequency_output(f);

        db = Data_Reader(f) * 100 / 12;

        if (db > avd) db = avd;

        add_data(f, (int)db);

        if (f > 50000 && db <= avd * 0.707 && fH == 0) {
            fH = f;
            setfH(fH);
        }

        if (f == 1000) add_data(0, (int)db);

        if ((f <= 100000 && f % 1000 == 0) || (f <= 300000 && f % 5000 == 0) ||
            (f <= 800000 && f % 10000 == 0) || (f % 40000 == 0)) {
            reset_pos();
            refresh_page1();
        }
    }

    reset_pos();
    refresh_page1();

    for (f = fH - 2000;; f += 100) {
        frequency_output(f);

        db = Data_Reader(f) * 100 / 12;

        if (db > avd) db = avd;

        add_data(f, (int)db);

        if (db <= avd * 0.707) {
            fH = f;
            setfH(fH);
            break;
        }
    }

    for (f = fH - 200;; f += 10) {
        frequency_output(f);

        db = Data_Reader(f) * 100 / 12;

        if (db > avd) db = avd;

        add_data(f, (int)db);

        if (db <= avd * 0.707) {
            fH = f;
            setfH(fH);
            break;
        }
    }

    for (f = fH - 20;; f++) {
        frequency_output(f);

        db = Data_Reader(f) * 100 / 12;

        if (db > avd) db = avd;

        add_data(f, (int)db);

        if (db <= avd * 0.707) {
            fH = f;
            break;
        }
    }

    setfH(fH);
    refresh_page1();

    outputer(0);
    outputer(1);
    outputer(2);

    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
    HAL_Delay(100);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
}

void ADC_Reader(double *max, double *min, double *avg) {
    static uint16_t adc_data[10];

    memcpy(adc_data, dma_buffer, sizeof(adc_data));

    *max = 0;
    *min = 5000;
    *avg = 0;

    double v;
    for (int i = 0; i < 50; i++) {
        v = (adc_data[i * 2 + 1] + 0.0) / adc_data[i * 2] * 1800;

        if (v > *max) *max = v;

        if (v < *min) *min = v;

        *avg += v;
    }

    *avg /= 50;
}

double Data_Reader(uint32_t f) {
    static double max, min, avg;

    int16_t flag = 5;

    leak_valve(1);
    while (flag) {
        leak_valve(1);

        ADC_Reader(&max, &min, &avg);

        flag -= (min < 250) || (max - min > 40);
    }

    if (!f) HAL_Delay(100);

    leak_valve(0);

    if (f <= 10000)
        flag = 250;
    else if (f <= 100000)
        flag = 200;
    else if (f <= 150000)
        flag = 180;
    else if (f <= 200000)
        flag = 100;
    else if (f <= 500000)
        flag = 50;
    else if (f <= 800000)
        flag = 30;
    else if (f <= 1200000)
        flag = 20;
    else
        flag = 10;

    while (flag > 0) {
        ADC_Reader(&max, &min, &avg);

        flag -= max - min < 10;
    }

    if (f <= 150000) HAL_Delay(10);

    if (!f) HAL_Delay(1000);

    ADC_Reader(&max, &min, &avg);

    return avg;
}